#include "sqlite-sql-record.h"
#include "hk_log.h"
#define HK_MACHINE_LOG_SUFFIX_FILE "ir-software-m"

st_sql_record::st_sql_record()
    : mb_empty( false ),
      mb_is_eof( false ),
      mp_sql_stmt( NULL ),
      mi_row_index( -1 ),
      mi_cols( 0 )
{
    m_col_map.clear();
}

st_sql_record::~st_sql_record()
{
    m_col_map.clear();
}

bool st_sql_record::is_eof()
{
    return mb_is_eof;
}

bool st_sql_record::move_next()
{
    if( mb_empty ){
        return false;
    }

    int i_ret = sqlite3_step( mp_sql_stmt );
    if( SQLITE_ROW == i_ret ){
        mi_row_index++;
        return true;
    } else if( SQLITE_DONE == i_ret ){
        mb_is_eof = true;
    }

    return false;
}

bool st_sql_record::get_field_value( std::string &str_field, int &i_value )
{    
    i_value = 0;
    std::map<std::string, int>::iterator it = m_col_map.find( str_field );
    if( it == m_col_map.end() ){
        return false;
    }

    i_value = sqlite3_column_int( mp_sql_stmt, it->second );
    return true;
}

bool st_sql_record::get_field_value( std::string &str_field, unsigned int &ui_value )
{
    ui_value = 0;
    std::map<std::string, int>::iterator it = m_col_map.find( str_field );
    if( it == m_col_map.end() ){
        return false;
    }

    ui_value = (unsigned int)sqlite3_column_int( mp_sql_stmt, it->second );
    return true;
}

bool st_sql_record::get_field_value( std::string &str_field, long long &i_value )
{
    i_value = 0;
    std::map<std::string, int>::iterator it = m_col_map.find( str_field );
    if( it == m_col_map.end() ){
        return false;
    }

    i_value = sqlite3_column_int64( mp_sql_stmt, it->second );
    return true;
}

bool st_sql_record::get_field_value( std::string &str_field, std::string &str )
{
    str.clear();
    std::map<std::string, int>::iterator it = m_col_map.find( str_field );
    if( it == m_col_map.end() ){
        return false;
    }

    const char *pstr = (const char*)sqlite3_column_text( mp_sql_stmt, it->second );
    if( pstr != NULL ){
        str = pstr;
    }

    return true;
}

bool st_sql_record::get_field_value( std::string &str_field, const void* &p_buffer, int &i_len )
{
    p_buffer = NULL;
    i_len = 0;

    std::map<std::string, int>::iterator it = m_col_map.find( str_field );
    if( it == m_col_map.end() ){
        return false;
    }

    p_buffer = sqlite3_column_blob(mp_sql_stmt, it->second);

    i_len = sqlite3_column_bytes(mp_sql_stmt, it->second);

    return true;
}

void st_sql_record::get_fields( std::vector<std::string> &field_vec )
{
    field_vec.clear();
    if( m_col_map.empty() ) {
        return;
    }

    std::list<st_field> field_list;
    field_list.resize( m_col_map.size() );

    do
    {
        std::map<std::string, int>::iterator it = m_col_map.begin();
        for (; it != m_col_map.end(); ++it) {
            st_field temp;
            temp.str_field = it->first;
            temp.i_index = it->second;

            field_list.push_back( temp );
        }

    } while (0);

    field_list.sort();

    do
    {
        std::list<st_field>::iterator it = field_list.begin();
        for (; it != field_list.end(); ++it) {
            field_vec.push_back(it->str_field);
        }
    } while (0);

    return;
}

bool st_sql_record::init()
{
    int i_ret = sqlite3_step( mp_sql_stmt );
    if (SQLITE_ROW == i_ret) {

    } else if (SQLITE_DONE == i_ret) {
        mb_is_eof = true;
    } else {
        return false;
    }

    mi_cols = sqlite3_column_count( mp_sql_stmt );
    for ( int i = 0; i < mi_cols; ++i )  {
        const char* pColName = sqlite3_column_name( mp_sql_stmt, i );
        if (pColName) {
            m_col_map[ std::string(pColName) ] = i;
        }
    }

    return true;

}

bool st_sql_record::exit()
{
    int i_ret = sqlite3_finalize( mp_sql_stmt );
    if (SQLITE_OK != i_ret) {
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "CSQLRecordSet::Exit sqlite3_finalize Failed, Ret=%d.\n", i_ret);
        return false;
    }

    return true;
}
